package com.zenithmind.document.pojo.domain;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.zenithmind.common.base.BaseEntity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import jakarta.validation.constraints.*;
import java.time.LocalDateTime;

/**
 * 文档收藏聚合根
 * 遵循单一职责原则：专注于收藏关系管理
 * 遵循封装原则：通过方法控制收藏状态
 * 遵循开闭原则：支持收藏夹扩展
 *
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@TableName("document_favorite")
@Schema(description = "文档收藏聚合根")
public class DocumentFavorite extends BaseEntity {

    /**
     * 收藏状态枚举
     */
    public enum FavoriteStatus {
        ACTIVE(1, "有效"),
        CANCELLED(0, "已取消");

        private final int code;
        private final String description;

        FavoriteStatus(int code, String description) {
            this.code = code;
            this.description = description;
        }

        public int getCode() { return code; }
        public String getDescription() { return description; }

        public static FavoriteStatus fromCode(int code) {
            for (FavoriteStatus status : values()) {
                if (status.code == code) {
                    return status;
                }
            }
            throw new IllegalArgumentException("未知的收藏状态代码: " + code);
        }
    }

    /**
     * 文档ID
     */
    @NotBlank(message = "文档ID不能为空")
    @TableField("document_id")
    @Schema(description = "文档ID")
    private String documentId;

    /**
     * 用户ID
     */
    @NotBlank(message = "用户ID不能为空")
    @TableField("user_id")
    @Schema(description = "用户ID")
    private String userId;

    /**
     * 收藏夹名称
     */
    @Size(max = 100, message = "收藏夹名称长度不能超过100个字符")
    @TableField("folder_name")
    @Schema(description = "收藏夹名称")
    private String folderName = "默认收藏夹";

    /**
     * 收藏备注
     */
    @Size(max = 500, message = "收藏备注长度不能超过500个字符")
    @TableField("note")
    @Schema(description = "收藏备注")
    private String note;

    /**
     * 收藏标签
     */
    @Size(max = 200, message = "收藏标签长度不能超过200个字符")
    @TableField("tags")
    @Schema(description = "收藏标签")
    private String tags;

    /**
     * 收藏状态
     */
    @NotNull(message = "收藏状态不能为空")
    @TableField("status")
    @Schema(description = "收藏状态")
    private Integer status;

    /**
     * 排序值
     */
    @Min(value = 0, message = "排序值不能为负数")
    @TableField("sort_order")
    @Schema(description = "排序值")
    private Integer sortOrder = 0;

    /**
     * 收藏时间
     */
    @TableField("favorite_time")
    @Schema(description = "收藏时间")
    private LocalDateTime favoriteTime;

    /**
     * 最后访问时间
     */
    @TableField("last_access_time")
    @Schema(description = "最后访问时间")
    private LocalDateTime lastAccessTime;

    // ========== 业务方法 ==========

    /**
     * 创建收藏
     */
    public static DocumentFavorite create(String documentId, String userId, String folderName) {
        DocumentFavorite favorite = new DocumentFavorite();
        favorite.setDocumentId(documentId);
        favorite.setUserId(userId);
        favorite.setFolderName(folderName);
        favorite.setStatus(FavoriteStatus.ACTIVE.getCode());
        favorite.setFavoriteTime(LocalDateTime.now());
        favorite.setSortOrder(0);
        return favorite;
    }

    /**
     * 设置文档ID
     */
    public void setDocumentId(String documentId) {
        if (documentId == null || documentId.trim().isEmpty()) {
            throw new IllegalArgumentException("文档ID不能为空");
        }
        this.documentId = documentId;
    }

    /**
     * 设置用户ID
     */
    public void setUserId(String userId) {
        if (userId == null || userId.trim().isEmpty()) {
            throw new IllegalArgumentException("用户ID不能为空");
        }
        this.userId = userId;
    }

    /**
     * 设置收藏夹名称
     */
    public void setFolderName(String folderName) {
        if (folderName != null && folderName.length() > 100) {
            throw new IllegalArgumentException("收藏夹名称长度不能超过100个字符");
        }
        this.folderName = folderName != null ? folderName : "默认收藏夹";
    }

    /**
     * 设置收藏备注
     */
    public void setNote(String note) {
        if (note != null && note.length() > 500) {
            throw new IllegalArgumentException("收藏备注长度不能超过500个字符");
        }
        this.note = note;
    }

    /**
     * 设置收藏标签
     */
    public void setTags(String tags) {
        if (tags != null && tags.length() > 200) {
            throw new IllegalArgumentException("收藏标签长度不能超过200个字符");
        }
        this.tags = tags;
    }

    /**
     * 设置收藏状态
     */
    public void setStatus(Integer status) {
        if (status == null) {
            throw new IllegalArgumentException("收藏状态不能为空");
        }
        // 验证状态值是否有效
        FavoriteStatus.fromCode(status);
        this.status = status;
    }

    /**
     * 设置排序值
     */
    public void setSortOrder(Integer sortOrder) {
        if (sortOrder != null && sortOrder < 0) {
            throw new IllegalArgumentException("排序值不能为负数");
        }
        this.sortOrder = sortOrder != null ? sortOrder : 0;
    }

    /**
     * 设置收藏时间
     */
    public void setFavoriteTime(LocalDateTime favoriteTime) {
        this.favoriteTime = favoriteTime;
    }

    /**
     * 设置最后访问时间
     */
    public void setLastAccessTime(LocalDateTime lastAccessTime) {
        this.lastAccessTime = lastAccessTime;
    }

    /**
     * 获取收藏状态枚举
     */
    public FavoriteStatus getFavoriteStatus() {
        return status != null ? FavoriteStatus.fromCode(status) : null;
    }

    /**
     * 检查是否为有效收藏
     */
    public boolean isActive() {
        return FavoriteStatus.ACTIVE.getCode() == (status != null ? status : -1);
    }

    /**
     * 激活收藏
     */
    public void activate() {
        this.status = FavoriteStatus.ACTIVE.getCode();
        this.favoriteTime = LocalDateTime.now();
    }

    /**
     * 取消收藏
     */
    public void cancel() {
        this.status = FavoriteStatus.CANCELLED.getCode();
    }

    /**
     * 更新访问时间
     */
    public void updateAccessTime() {
        this.lastAccessTime = LocalDateTime.now();
    }

    /**
     * 移动到收藏夹
     */
    public void moveToFolder(String newFolderName) {
        setFolderName(newFolderName);
    }

    /**
     * 添加标签
     */
    public void addTag(String tag) {
        if (tag == null || tag.trim().isEmpty()) {
            return;
        }

        if (this.tags == null || this.tags.trim().isEmpty()) {
            this.tags = tag.trim();
        } else {
            // 检查标签是否已存在
            String[] existingTags = this.tags.split(",");
            for (String existingTag : existingTags) {
                if (existingTag.trim().equals(tag.trim())) {
                    return; // 标签已存在
                }
            }
            this.tags += "," + tag.trim();
        }

        // 检查长度限制
        if (this.tags.length() > 200) {
            throw new IllegalArgumentException("收藏标签长度不能超过200个字符");
        }
    }

    /**
     * 移除标签
     */
    public void removeTag(String tag) {
        if (tag == null || tag.trim().isEmpty() || this.tags == null) {
            return;
        }

        String[] existingTags = this.tags.split(",");
        StringBuilder newTags = new StringBuilder();

        for (String existingTag : existingTags) {
            if (!existingTag.trim().equals(tag.trim())) {
                if (newTags.length() > 0) {
                    newTags.append(",");
                }
                newTags.append(existingTag.trim());
            }
        }

        this.tags = newTags.toString();
    }

    /**
     * 检查是否包含标签
     */
    public boolean hasTag(String tag) {
        if (tag == null || tag.trim().isEmpty() || this.tags == null) {
            return false;
        }

        String[] existingTags = this.tags.split(",");
        for (String existingTag : existingTags) {
            if (existingTag.trim().equals(tag.trim())) {
                return true;
            }
        }

        return false;
    }

    /**
     * 获取标签列表
     */
    public String[] getTagList() {
        if (this.tags == null || this.tags.trim().isEmpty()) {
            return new String[0];
        }

        return this.tags.split(",");
    }

    /**
     * 检查收藏信息是否完整
     */
    public boolean isComplete() {
        return documentId != null && !documentId.trim().isEmpty() &&
               userId != null && !userId.trim().isEmpty() &&
               status != null;
    }

    /**
     * 检查是否为默认收藏夹
     */
    public boolean isDefaultFolder() {
        return "默认收藏夹".equals(folderName);
    }

    /**
     * 获取收藏天数
     */
    public long getFavoriteDays() {
        if (favoriteTime == null) {
            return 0;
        }

        return java.time.Duration.between(favoriteTime, LocalDateTime.now()).toDays();
    }

    /**
     * 检查是否为最近收藏
     */
    public boolean isRecentFavorite(int days) {
        return getFavoriteDays() <= days;
    }
}
